/**
 * Copyright (c) 2017-2018, zengjintao (1913188966@qq.com).
 * <p>
 * Licensed under the GNU Lesser General Public License (LGPL) ,Version 3.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.gnu.org/licenses/lgpl-3.0.txt
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.jfast.framework.server.jetty;


import java.io.File;
import java.io.IOException;

import com.jfast.framework.web.core.JfastCoreHttpServlet;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.SessionManager;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.server.session.HashSessionManager;
import org.eclipse.jetty.server.session.SessionHandler;
import org.eclipse.jetty.webapp.WebAppClassLoader;
import org.eclipse.jetty.webapp.WebAppContext;
import com.jfast.framework.kit.FileKit;
import com.jfast.framework.kit.PathKit;
import com.jfast.framework.server.JfastServer;
import com.jfast.framework.web.core.JfastWebListener;


public class JettyServer extends JfastServer {

	private static final String PATHPEC = "/*";
	
	private Server server;
	
	private WebAppContext webAppContext;
	
	public JettyServer(){
		super();
	}
	
	@Override
	public void restart() {
		super.restart();
	}
	
	
	@Override
	public void doStart() throws IOException {
		deleteSessionData();
		
	    server = new Server();
	    SelectChannelConnector connector = new SelectChannelConnector();
		connector.setPort(jfastServerConfig.getPort());
		server.addConnector(connector);
		webAppContext = new WebAppContext();
		webAppContext.setContextPath(jfastServerConfig.getContextPath());
		webAppContext.setResourceBase(jfastServerConfig.getResourceLocation());
		
		//加载JfastWebListener监听器
		webAppContext.addEventListener(new JfastWebListener());
		
		//加载核心处理器CoreHttpServlet
		webAppContext.addServlet(JfastCoreHttpServlet.class, PATHPEC);
		
		persistSession(webAppContext);
		server.setHandler(webAppContext);
		
		new JfastClassLoaderScanner() {
			@Override
			void onChange() {
				try {
					System.err.println("\nLoading changes ......");
					webAppContext.stop();
					changeClassLoader(webAppContext);
					webAppContext.start();
					System.err.println("Loading complete.");
				} catch (Exception e) {
					
				}
			}
		}.start();
		
		try {
			server.start();
			printSuccesInfo();
			server.join();
		} catch (Exception e) {
			e.printStackTrace();
			System.err.println("Starting jetty failed :)");
		}
	}
	
	private void changeClassLoader(WebAppContext webApp) {
		try {
			webApp.setClassLoader(new WebAppClassLoader(webApp));
		} catch (IOException e1) {
			throw new IllegalStateException(e1);
		}
	}

	private void deleteSessionData() {
		try {
			FileKit.delete(new File(getStoreDir()));
		}
		catch (Exception e) {
		}
	}
	
	private String getStoreDir() {
		String storeDir = PathKit.getWebRootPath() + "/../../session_data" + getJfastServerConfig().getContextPath();
		if ("\\".equals(File.separator)) {
			storeDir = storeDir.replaceAll("/", "\\\\");
		}
		return storeDir;
	}

	private void persistSession(WebAppContext webApp) throws IOException {
		String storeDir = getStoreDir();
		SessionManager sm = webApp.getSessionHandler().getSessionManager();
		if (sm instanceof HashSessionManager) {
			((HashSessionManager)sm).setStoreDirectory(new File(storeDir));
			return ;
		}
		HashSessionManager hsm = new HashSessionManager();
		hsm.setStoreDirectory(new File(storeDir));
		SessionHandler sh = new SessionHandler();
		sh.setSessionManager(hsm);
		webApp.setSessionHandler(sh);
	}
	
	@Override
	public void stop() {
		super.stop();
	}

	@Override
	public void doReStart() {
		this.stop();
		this.restart();
	}
	
	@SuppressWarnings("unused")
	private class JfastClassLoader extends WebAppClassLoader{
		public JfastClassLoader(Context context) throws IOException {
			super(context);
			for (String path : getClassPath().split(String.valueOf(File.pathSeparatorChar))) {
				if (path.startsWith("-y-") || path.startsWith("-n-")) {
					path = path.substring(3);
				}

				if (path.startsWith("-n-") == false) {
					super.addClassPath(path);
				}
			}
		}
		
		private String getClassPath() {
			return System.getProperty("java.class.path");
		}
	}
}




